package com.yonyou.sto.modules.ums.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.yonyou.sto.common.api.CommonResult;
import com.yonyou.sto.modules.ims.dto.TaxItemDto;
import com.yonyou.sto.modules.ims.model.ImsParty;
import com.yonyou.sto.modules.ims.model.ImsTaxItem;
import com.yonyou.sto.modules.ims.service.impl.PushBillServiceImpl;
import com.yonyou.sto.modules.ums.dto.UmsNcCusttaxParam;
import com.yonyou.sto.modules.ums.model.UmsAdmin;
import com.yonyou.sto.modules.ums.model.UmsNcCustomer;
import com.yonyou.sto.modules.ums.model.UmsNcCusttax;
import com.yonyou.sto.modules.ums.mapper.UmsNcCusttaxMapper;
import com.yonyou.sto.modules.ums.model.UmsNcMategrade;
import com.yonyou.sto.modules.ums.service.UmsNcCustomerService;
import com.yonyou.sto.modules.ums.service.UmsNcCusttaxService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.yonyou.sto.modules.ums.service.UmsNcMategradeService;
import com.yonyou.sto.modules.ums.util.NCCusttaxUtil;
import com.yonyou.sto.modules.ums.util.NcMateGradeUtil;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.xssf.usermodel.XSSFCell;
import org.apache.poi.xssf.usermodel.XSSFRow;
import org.apache.poi.xssf.usermodel.XSSFSheet;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import java.io.IOException;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

/**
 * <p>
 *  服务实现类
 * </p>
 *
 * @author aegon
 * @since 2022-11-25
 */
@Service
public class UmsNcCusttaxServiceImpl extends ServiceImpl<UmsNcCusttaxMapper, UmsNcCusttax> implements UmsNcCusttaxService {

    private static final Logger LOGGER = LoggerFactory.getLogger(UmsNcCusttaxServiceImpl.class);

    @Autowired
    private UmsNcMategradeService umsNcMategradeService;

    @Autowired
    private UmsNcCustomerService umsNcCustomerService;

    @Resource
    private ConfigNameServicImpl configNameServic;

    @Override
    public Page<UmsNcCusttax> list(String def1,String def3,String def4,String taxcode, Integer pageSize, Integer pageNum) {
        Page<UmsNcCusttax> page = new Page<>(pageNum, pageSize);
        QueryWrapper<UmsNcCusttax> wrapper = new QueryWrapper<>();
        LambdaQueryWrapper<UmsNcCusttax> lambda = wrapper.lambda();
        lambda.eq(UmsNcCusttax::getDr, 0);//NC dr=0为未被删除
        if (StrUtil.isNotEmpty(def1)) {
            lambda.like(UmsNcCusttax::getDef1, def1);
        }
        if (StrUtil.isNotEmpty(def3)) {
            lambda.like(UmsNcCusttax::getDef3, def3);
        }
        if (StrUtil.isNotEmpty(def4)) {
            lambda.like(UmsNcCusttax::getDef4, def4);
        }
        if (StrUtil.isNotEmpty(taxcode)) {
            lambda.like(UmsNcCusttax::getTaxcode, taxcode);
        }
        lambda.orderByAsc(UmsNcCusttax::getDef1);
        Page<UmsNcCusttax> page1 = page(page, wrapper);
        List<UmsNcCusttax> records = page1.getRecords();
        List<UmsNcCusttax> collect = records.stream().map(m -> {
            m.setDef5(configNameServic.getCusttaxCofigName(m));
            return m;
        }).collect(Collectors.toList());
        page1.setRecords(collect);
        return page1;
    }

    @Override
    public CommonResult<UmsNcCusttax> info(String id) {
        UmsNcCusttax umsNcCusttax = getById(id);
        List<String> mateName = NCCusttaxUtil.getMateName(umsNcCusttax);
        umsNcCusttax.setCustMateNames(mateName);
        List<String> specModel = NCCusttaxUtil.getSpecModel(umsNcCusttax);
        umsNcCusttax.setSpecModel(specModel);
        return CommonResult.success(umsNcCusttax);
    }

    @Override
    public CommonResult create(UmsNcCusttax umsNcCusttax) {
        //获取物料分类主键，根据物料分类主键查询出物料分类名称和物料分类编码
        String pkMategrade = umsNcCusttax.getPkMategrade();
        if (pkMategrade==null) return CommonResult.failed("物料信息不存在");
        UmsNcMategrade umsNcMategrade = umsNcMategradeService.getById(pkMategrade);
        if (umsNcMategrade==null) return CommonResult.failed("物料信息不存在");
        if (StrUtil.isNotBlank(umsNcMategrade.getPkNc())){
            umsNcCusttax.setDef7(umsNcMategrade.getPkNc());
        }

        //获取客户名称，根据客户主键查询出客户名称和客户编码
        String pkCustomer = umsNcCusttax.getPkCustomer();
        if (pkCustomer==null) return CommonResult.failed("客户信息不存在");
        UmsNcCustomer umsNcCustomer = umsNcCustomerService.getById(pkCustomer);
        if (umsNcCustomer==null) return CommonResult.failed("客户信息不存在");
        if (StrUtil.isNotBlank(umsNcCustomer.getPkNc())){
            umsNcCusttax.setDef8(umsNcCustomer.getPkNc());
        }
        UmsNcCusttax one = getOne(new LambdaQueryWrapper<UmsNcCusttax>().eq(UmsNcCusttax::getPkNccust, umsNcCusttax.getPkNccust()).eq(UmsNcCusttax::getPkNcmateg, umsNcCusttax.getPkNcmateg()));
        if (one!=null){
            return CommonResult.failed("客户对照关系已经存在");
        }
        //准备客户物料名称
        boolean result1 = NCCusttaxUtil.setCustMateName(umsNcCusttax);
        boolean result2 = NCCusttaxUtil.setSpecModel(umsNcCusttax);
        if (result1&&result2){
            //umsNcCusttax.setPkCusttax("202212012027");
            umsNcCusttax.setDr("0");
            umsNcCusttax.setCreatetime(new SimpleDateFormat("yyyy-MM-dd HH-mm:ss").format(new Date()));
            boolean save = save(umsNcCusttax);
            if (save){
                configNameServic.setumsNcCusttax(umsNcCusttax);
                //configNameServic.setumsNcMategrade(umsNcMategrade);
                return CommonResult.success("新增成功");
            }
        }

        return CommonResult.success(save(umsNcCusttax));
    }

    @Override
    public CommonResult update(String pkCusttax, UmsNcCusttax umsNcCusttax) {
        UmsNcCusttax byId = getById(pkCusttax);
        String pkCustomer = umsNcCusttax.getPkCustomer();
        String pkMategrade = umsNcCusttax.getPkMategrade();
        UmsNcCustomer umsNcCustomer = umsNcCustomerService.getOne(new LambdaQueryWrapper<UmsNcCustomer>()
                .eq(UmsNcCustomer::getPkNc, umsNcCusttax.getPkNccust()));
        if (umsNcCustomer==null) return CommonResult.failed("客户主键不存在");

        UmsNcMategrade umsNcMategrade = umsNcMategradeService.getOne(new LambdaQueryWrapper<UmsNcMategrade>()
                .eq(UmsNcMategrade::getPkNc,umsNcCusttax.getPkNcmateg()));
        if (umsNcMategrade==null)return CommonResult.failed("物料主键不存在");
        byId.setPkCustomer(pkCustomer);
        byId.setDef1(umsNcCustomer.getName());
        byId.setDef2(umsNcCustomer.getCode());
        byId.setPkMategrade(pkMategrade);
        byId.setPkNccust(umsNcCustomer.getPkNc());
        byId.setPkNcmateg(umsNcMategrade.getPkNc());
        byId.setDef3(umsNcMategrade.getName());
        byId.setDef4(umsNcMategrade.getCode());
        byId.setDef7(umsNcMategrade.getPkNc());
        byId.setDef8(umsNcCustomer.getPkNc());
        NCCusttaxUtil.toOrigin(byId);
        byId.setCustMateNames(umsNcCusttax.getCustMateNames());
        byId.setSpecModel(umsNcCusttax.getSpecModel());
        byId.setCompany(umsNcCusttax.getCompany());
        byId.setTaxcode(umsNcCusttax.getTaxcode());
        byId.setTaxname(umsNcCusttax.getTaxname());
        byId.setDef11(umsNcCusttax.getDef11());
        byId.setDef12(umsNcCusttax.getDef12());
        boolean result1 = NCCusttaxUtil.setCustMateName(byId);
        boolean result2 = NCCusttaxUtil.setSpecModel(byId);
        if (result1&&result2){
            umsNcCusttax.setUpdatetime(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()));
            boolean result = updateById(byId);
            if (result){
                //configNameServic.setumsNcCusttax(byId);
                return CommonResult.success("修改成功");
            }
        }
        return CommonResult.failed("修改失败");
    }

    @Override
    @Transactional
    public boolean delUmsNcCusttax(List<String> ids) {
        for (String id:ids) {
            boolean flag = removeById(id);
        }
        return true;
    }

    /**
     * 导入的客户对照关系中，客户物料名称和规格型号的配置怎么去弄？
     * @param file
     * @return
     */
    @Override
    public CommonResult importNcCusttax(MultipartFile file) {
        LOGGER.debug("导入客户对照关系"+file.getName());

        String fileName = file.getOriginalFilename();
        if (!fileName.matches("^.+\\.(?i)(xlsx)$")) {
            return CommonResult.failed("请上传excel2007版本及以上的xlsx文件");
        }

        try {
            XSSFWorkbook xssf = new XSSFWorkbook(file.getInputStream());
            int numberOfSheets = xssf.getNumberOfSheets();

            List<UmsNcCusttax> ncCusttaxes = new ArrayList<>();
            List<UmsNcCusttax> ncCusttaxes1 = new ArrayList<>();
            for (int i = 0; i < numberOfSheets; i++) {// 表
                XSSFSheet sheet = xssf.getSheetAt(i);
                int physicalNumberOfRows = sheet.getPhysicalNumberOfRows();
                for (int j = 0; j < physicalNumberOfRows; j++) {// 行
                    if (j == 0) continue;
                    XSSFRow row = sheet.getRow(j);
                    int physicalNumberOfCells = row.getPhysicalNumberOfCells();

                    UmsNcCusttax ncCusttax = new UmsNcCusttax();
                    Field[] f = ncCusttax.getClass().getDeclaredFields();

                    for (int k = 0; k < physicalNumberOfCells; k++) {// 单元格
                        row.getCell(k).setCellType(Cell.CELL_TYPE_STRING);
                        XSSFCell cell = row.getCell(k);
                        String stringCellValue = cell.getStringCellValue();
                        // 此方法要求导入格式必须正确 索引从1开始
                        String attributeName = f[k + 2].getName();
                        String methodName = attributeName.substring(0, 1).toUpperCase() + attributeName.substring(1);
                        Method setMethod = ncCusttax.getClass().getMethod("set" + methodName, String.class);
                        if(attributeName.contains("custtax")){
                            if (StrUtil.isNotBlank(stringCellValue)&&stringCellValue.equals("Y")){
                                setMethod.invoke(ncCusttax, "1");
                            }else {
                                setMethod.invoke(ncCusttax, "0");
                            }
                        }else {
                            if (attributeName.contains("def9")||attributeName.contains("def10")){
                                if (StrUtil.isNotBlank(stringCellValue)&&stringCellValue.equals("Y")){
                                    setMethod.invoke(ncCusttax, "1");
                                }else {
                                    setMethod.invoke(ncCusttax, "0");
                                }
                            }else {
                                setMethod.invoke(ncCusttax, stringCellValue);
                            }
                        }
                    }
                    ncCusttax.setCreatetime(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()));
                    ncCusttax.setDr("0");
                    UmsNcCustomer one = umsNcCustomerService.getOne(new LambdaQueryWrapper<UmsNcCustomer>().eq(UmsNcCustomer::getName, ncCusttax.getDef1()));//def1是客户名称
                    UmsNcMategrade one1 = umsNcMategradeService.getOne(new LambdaQueryWrapper<UmsNcMategrade>().eq(UmsNcMategrade::getCode, ncCusttax.getDef4()));//def3是物料名称
                    if (one == null) return CommonResult.failed("请检查客户信息，"+ncCusttax.getDef1()+"不存在");
                    if (one1 == null) return CommonResult.failed("请检查物料分类，物料"+ncCusttax.getDef3()+"不存在");
                    ncCusttax.setPkCustomer(one.getPkCustomer());
                    ncCusttax.setPkNccust(one.getPkNc());
                    ncCusttax.setPkMategrade(one1.getPkMategrade());
                    ncCusttax.setPkNcmateg(one1.getPkNc());
                    UmsNcCusttax one2 = getOne(new LambdaQueryWrapper<UmsNcCusttax>().eq(UmsNcCusttax::getPkNccust, ncCusttax.getPkNccust()).eq(UmsNcCusttax::getPkNcmateg, ncCusttax.getPkNcmateg()));
                    if (one2==null){
                        ncCusttaxes.add(ncCusttax);
                    }else {
                        ncCusttax.setPkCusttax(one2.getPkCusttax());
                        ncCusttaxes1.add(ncCusttax);
                    }
                }
            }
            for (UmsNcCusttax ncCusttax : ncCusttaxes) {
                save(ncCusttax);
            }

            for (UmsNcCusttax umsNcCusttax : ncCusttaxes1) {
                updateById(umsNcCusttax);
            }
            /*for (UmsNcCusttax umsNcCusttax:ncCusttaxes) {
                configNameServic.setumsNcCusttax(umsNcCusttax);
            }*/
            return CommonResult.success("上传文件成功");
        } catch (IOException | NoSuchMethodException | IllegalAccessException | InvocationTargetException | NullPointerException e) {
            e.printStackTrace();
            return CommonResult.failed("上传文件格式不正确");
        }
    }
}
